#include<iostream>
#include<fstream>
#include<direct.h>
#include "GeoUtil.h"
using namespace std;

struct Paras
{
	string *Data = NULL;
	int count = 0;
};

int main(int argc, char* argv[]){

	string projectPath(argv[0]);
	projectPath = projectPath.substr(0, projectPath.find_last_of("\\"));

	//set GDAL_DATA
	CPLSetConfigOption("GDAL_DATA", (projectPath + "\\" + string("gdal-data")).c_str());
	cout << (projectPath + "\\" + string("gdal-data")).c_str() << endl;
	GeoUtil *geoUtil = new  GeoUtil(projectPath);
	geoUtil->imageProcessing("E:\\Kuner\\gdal221\\testData\\point\\dest_pro.tif", 9,"E:\\Kuner\\gdal221\\testData\\point\\dest_pro_img.bmp");
	system("pause");
	return 0;
	
	string MethodName = "";

	if (argc == 1){
		cout << "unknown command ,-h to get help." << endl;
		cout << "-m buffer -p [Input] [DistancePath] [Output]" << endl;
		cout << "-m delaunay -p [Input] [dfTolerancePath] [bOnlyEdgesPath] [output]" << endl;
		cout << "-m diff -p [Input1] [Input2] [output]" << endl;
		cout << "-m symdiff -p [Input1] [Input2] [output]" << endl;
		cout << "-m intersect -p [Input1] [Input2] [output]" << endl;
		cout << "-m union -p [Input1] [Input2] [output]" << endl;
		cout << "-m projection -p [Input][output]  (just to EPSG:4326)" << endl;
		cout << "-m vonoroi -p [Input][output]  (just point)" << endl;
		return 0;
	}
	if (argc >= 2){
		Paras mParas;
		if (string(argv[1]) == string("-h")){
			cout << "-m buffer -p [Input] [DistancePath] [Output]" << endl;
			cout << "-m delaunay -p [Input] [dfTolerancePath] [bOnlyEdgesPath] [output]" << endl;
			cout << "-m diff -p [Input1] [Input2] [output]" << endl;
			cout << "-m symdiff -p [Input1] [Input2] [output]" << endl;
			cout << "-m intersect -p [Input1] [Input2] [output]" << endl;
			cout << "-m union -p [Input1] [Input2] [output]" << endl;
			cout << "-m projection -p [Input][output]  (just to EPSG:4326)" << endl;
			cout << "-m vonoroi -p [Input][output]  (just point)" << endl;
			return 0;
		}
		else if (string(argv[1]) == string("-m")){
			if (argc >4){
				MethodName = argv[2];
				if (string(argv[3]) == string("-p")){

					int ParasCount = argc - 4;
					if (ParasCount <= 0){
						cout << "no parameter for method " << MethodName << endl;
						return -1;
					}
					mParas.Data = new string[ParasCount];
					mParas.count = ParasCount;
					for (int i = 0; i < ParasCount; i++){
						mParas.Data[i] = argv[4 + i];
					}
				}
				else{
					cout << "no parameter for method." << MethodName << endl;
					return -1;
				}
			}
			else{
				cout << "unknown command." << endl;
				return 0;
			}
		}
		else if (string(argv[1]) == string("-p")){
			if ((_access((projectPath + "\\method.bat").c_str(), 0)) == -1){
				cout << "Config file does not exist." << endl;
				return -1;
			}
			ifstream fin(projectPath + "\\method.bat");
			fin >> MethodName;
			fin.close();

			int ParasCount = argc - 2;
			if (ParasCount <= 0){
				cout << "no parameter for method ." << MethodName << endl;
				return -1;
			}

			mParas.Data = new string[ParasCount];
			mParas.count = ParasCount;
			for (int i = 0; i < ParasCount; i++){
				mParas.Data[i] = argv[2 + i];
			}
		}
		else{
			cout << "unknown command ,-h to get help." << endl;
			cout << "-m buffer -p [Input] [DistancePath] [Output]" << endl;
			cout << "-m delaunay -p [Input] [dfTolerancePath] [bOnlyEdgesPath] [output]" << endl;
			cout << "-m diff -p [Input1] [Input2] [output]" << endl;
			cout << "-m symdiff -p [Input1] [Input2] [output]" << endl;
			cout << "-m intersect -p [Input1] [Input2] [output]" << endl;
			cout << "-m union -p [Input1] [Input2] [output]" << endl;
			cout << "-m projection -p [Input][output]  (just to EPSG:4326)" << endl;
			cout << "-m vonoroi -p [Input][output]  (just point)" << endl;
			
			return 0;
		}


		//excute method
		if (MethodName == string("projection")){
			if (mParas.count != 2){
				cout << "The number of parameters for this method is incorrect." << endl;
				return -1;
			}
			string inputPath(mParas.Data[0]);
			string outputpath(mParas.Data[1]);

			if ((_access((inputPath).c_str(), 0)) == -1){
				cout << inputPath << " does not exist." << endl;
				return -1;
			}

			if (GeoUtil::geoProjection(inputPath.c_str(), outputpath.c_str())){
				cout << MethodName << " calculation is complete." << endl;
			}
			else{
				cout << MethodName << " calculation failed." << endl;
				return -1;
			}
		}
		else if (MethodName == string("vonoroi")){
			if (mParas.count != 2){
				cout << "The number of parameters for this method is incorrect." << endl;
				return -1;
			}
			string inputPath(mParas.Data[0]);
			string outputpath(mParas.Data[1]);

			if ((_access((inputPath).c_str(), 0)) == -1){
				cout << inputPath << " does not exist." << endl;
				return -1;
			}

			if (GeoUtil::geoVonoroi(inputPath.c_str(), outputpath.c_str())){
				cout << MethodName << " calculation is complete." << endl;
			}
			else{
				cout << MethodName << " calculation failed." << endl;
				return -1;
			}
		}
		else if (MethodName == string("buffer")){

			if (mParas.count != 3){
				cout << "The number of parameters for this method is incorrect." << endl;
				return -1;
			}

			string inputPath(mParas.Data[0]);
			string distancePath(mParas.Data[1]);
			string outputpath(mParas.Data[2]);

			if ((_access((inputPath).c_str(), 0)) == -1){
				cout << inputPath << " does not exist." << endl;
				return -1;
			}
			if ((_access((distancePath).c_str(), 0)) == -1){
				cout << distancePath << " does not exist." << endl;
				return -1;
			}
			string distanceStr = "";
			ifstream fin(distancePath);
			fin >> distanceStr;
			fin.close();

			if (GeoUtil::geoBuffer(inputPath.c_str(), atof(distanceStr.c_str()), outputpath.c_str())){
				cout << MethodName << " calculation is complete" << endl;
			}
			else{
				cout << MethodName << " calculation failed." << endl;
				return -1;
			}

		}
		else if (MethodName == string("diff")){
			if (mParas.count != 3){
				cout << "The number of parameters for this method is incorrect." << endl;
				return -1;
			}
			string inputPath1(mParas.Data[0]);
			string inputPath2(mParas.Data[1]);
			string outputpath(mParas.Data[2]);

			if ((_access((inputPath1).c_str(), 0)) == -1){
				cout << inputPath1 << " does not exist." << endl;
				return -1;
			}
			if ((_access((inputPath2).c_str(), 0)) == -1){
				cout << inputPath2 << " does not exist." << endl;
				return -1;
			}

			if (GeoUtil::geoDifference(inputPath1.c_str(), inputPath2.c_str(), outputpath.c_str())){
				cout << MethodName << " calculation is complete." << endl;
			}
			else{
				cout << MethodName << " calculation failed." << endl;
				return -1;
			}
		}
		else if (MethodName == string("symdiff")){
			if (mParas.count != 3){
				cout << "The number of parameters for this method is incorrect." << endl;
				return -1;
			}
			string inputPath1(mParas.Data[0]);
			string inputPath2(mParas.Data[1]);
			string outputpath(mParas.Data[2]);

			if ((_access((inputPath1).c_str(), 0)) == -1){
				cout << inputPath1 << " does not exist." << endl;
				return -1;
			}
			if ((_access((inputPath2).c_str(), 0)) == -1){
				cout << inputPath2 << " does not exist." << endl;
				return -1;
			}

			if (GeoUtil::geoSymDifference(inputPath1.c_str(), inputPath2.c_str(), outputpath.c_str())){
				cout << MethodName << " calculation is complete." << endl;
			}
			else{
				cout << MethodName << " calculation failed." << endl;
				return -1;
			}
		}
		else if (MethodName == string("intersect")){

			if (mParas.count != 3){
				cout << "The number of parameters for this method is incorrect." << endl;
				return -1;
			}
			string inputPath1(mParas.Data[0]);
			string inputPath2(mParas.Data[1]);
			string outputpath(mParas.Data[2]);

			if ((_access((inputPath1).c_str(), 0)) == -1){
				cout << inputPath1 << " does not exist." << endl;
				return -1;
			}
			if ((_access((inputPath2).c_str(), 0)) == -1){
				cout << inputPath2 << " does not exist." << endl;
				return -1;
			}

			if (GeoUtil::geoIntersection(inputPath1.c_str(), inputPath2.c_str(), outputpath.c_str())){
				cout << MethodName << " calculation is complete." << endl;
			}
			else{
				cout << MethodName << " calculation failed." << endl;
				return -1;
			}
		}
		else if (MethodName == string("union")){
			if (mParas.count != 3){
				cout << "The number of parameters for this method is incorrect." << endl;
				return -1;
			}
			string inputPath1(mParas.Data[0]);
			string inputPath2(mParas.Data[1]);
			string outputpath(mParas.Data[2]);

			if ((_access((inputPath1).c_str(), 0)) == -1){
				cout << inputPath1 << " does not exist." << endl;
				return -1;
			}
			if ((_access((inputPath2).c_str(), 0)) == -1){
				cout << inputPath2 << " does not exist." << endl;
				return -1;
			}

			if (GeoUtil::geoUnion(inputPath1.c_str(), inputPath2.c_str(), outputpath.c_str())){
				cout << MethodName << " calculation is complete." << endl;
			}
			else{
				cout << MethodName << " calculation failed." << endl;
				return -1;
			}
		}
		else if (MethodName == string("delaunay")){

			if (mParas.count != 4){
				cout << "The number of parameters for this method is incorrect." << endl;
				return -1;
			}

			string inputPath(mParas.Data[0]);
			string dfTolerancePath(mParas.Data[1]);
			string bOnlyEdgesPath(mParas.Data[2]);
			string outputPath(mParas.Data[3]);

			if ((_access((inputPath).c_str(), 0)) == -1){
				cout << inputPath << " does not exist." << endl;
				return -1;
			}
			if ((_access((dfTolerancePath).c_str(), 0)) == -1){
				cout << dfTolerancePath << " does not exist." << endl;
				return -1;
			}
			if ((_access((bOnlyEdgesPath).c_str(), 0)) == -1){
				cout << bOnlyEdgesPath << " does not exist." << endl;
				return -1;
			}

			string dfToleranceStr = "";
			string bOnlyEdgesStr = "";

			ifstream fin(dfTolerancePath);
			fin >> dfToleranceStr;
			fin.close();

			ifstream fin2(bOnlyEdgesPath);
			fin2 >> bOnlyEdgesStr;
			fin2.close();

			bool bOnlyEdgesFlag = false;
			if (bOnlyEdgesStr == string("true")){
				bOnlyEdgesFlag = true;
			}
			if (GeoUtil::geoDelaunayTriangulation(inputPath.c_str(), atof(dfToleranceStr.c_str()), bOnlyEdgesFlag, outputPath.c_str())){
				cout << MethodName << " calculation is complete." << endl;
			}
			else{
				cout << MethodName << " calculation failed." << endl;
				return -1;
			}
		}
		else{
			cout << "config file is not correct." << endl;
			return -1;
		}
	}
	return 0;
}